package com.pingan.haofang.searchcloud.api.query.parser.dbobject;

import java.util.HashMap;
import java.util.Map;

import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.BinaryOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.EQOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.GEOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.GTOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.IsNotOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.IsOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.LEOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.LTOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.LikeOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.NEOperator;
import com.pingan.haofang.searchcloud.api.query.parser.dbobject.operator.NotLikeOperator;

public enum Operator {

    GT(new GTOperator(), ">"), GE(new GEOperator(), ">="), EQ(new EQOperator(), "="), LE(new LEOperator(), "<="),
    LT(new LTOperator(), "<"), LIKE(new LikeOperator(), "like"), NE(new NEOperator(), "!=", "<>"),
    NOT_LIKE(new NotLikeOperator(), "not like"),
    IS(new IsOperator(), "is"),
    IS_NOT(new IsNotOperator(), "is not"),;

    private static Map<String, Operator> MAP = new HashMap<String, Operator>();
    private static Map<Operator, Operator> REVERSE_MAP = new HashMap<Operator, Operator>();

    public final BinaryOperator operator;
    public final String[] values;

    static {
        for (Operator operator : values()) {
            for (String value : operator.values) {
                MAP.put(value, operator);
            }
        }

        REVERSE_MAP.put(GT, LT);
        REVERSE_MAP.put(GE, LE);
        REVERSE_MAP.put(EQ, EQ);
        REVERSE_MAP.put(LE, GE);
        REVERSE_MAP.put(LT, GT);
        REVERSE_MAP.put(LIKE, LIKE);
        REVERSE_MAP.put(NE, NE);
        REVERSE_MAP.put(NOT_LIKE, NOT_LIKE);
        REVERSE_MAP.put(IS, IS_NOT);
    }

    Operator(BinaryOperator operator, String...values) {
        this.operator = operator;
        this.values = values;
    }

    public boolean execute(Object left, Object right) {
        return operator.execute(left, right);
    }

    public static Operator getReverse(Operator source) {
        return REVERSE_MAP.get(source);
    }

    public static Operator get(String value) {
        return value == null ? null : MAP.get(value.toLowerCase());
    }
}
